package com.itheima.tlias.aspect;

import com.itheima.tlias.annotation.LoginLog;
import com.itheima.tlias.pojo.Emp;
import com.itheima.tlias.pojo.EmpLoginLog;
import com.itheima.tlias.pojo.LoginInfo;
import com.itheima.tlias.pojo.Result;
import com.itheima.tlias.service.EmpLoginLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Aspect
@Component
@Slf4j
public class LoginLogAspect {

    @Autowired
    private EmpLoginLogService empLoginLogService;

    //通过创建实例来实现切点的地址指向
    @Pointcut("@annotation(loginLog)")
    public void loginLogPointcut(LoginLog loginLog) {}

    @Around("loginLogPointcut(loginLog)")
    public Object around(ProceedingJoinPoint joinPoint, LoginLog loginLog) throws Throwable {
        EmpLoginLog empLoginLog = null;
        long startTime = System.currentTimeMillis();

        try {

            // 获取方法参数
            Object[] args = joinPoint.getArgs();
            // 检查参数列表是否包含Emp类型对象
            if (args.length > 0 && args[0] instanceof Emp) {
                // 类型转换并创建Emp对象
                Emp emp = (Emp) args[0];
                // 初始化员工登录日志对象，记录登录信息
                empLoginLog = EmpLoginLog.builder()
                        .username(emp.getUsername()) // 设置用户名
                        .password(emp.getPassword()) // 设置密码
                        .loginTime(LocalDateTime.now()) // 设置登录时间
                        .isSuccess(0) // 默认设置登录状态为失败
                        .build();
            }

            // 执行目标方法
            Object result = joinPoint.proceed();

            if (empLoginLog != null) {
                long endTime = System.currentTimeMillis();
                long costTime = endTime - startTime;
                empLoginLog.setCostTime((int) costTime);
                if (result instanceof Result) {
                    Result resultObj = (Result) result;
                    empLoginLog.setIsSuccess(resultObj.isSuccess() ? 1 : 0);
                    if (resultObj.isSuccess() && resultObj.getData() instanceof LoginInfo) {
                        LoginInfo loginInfo = (LoginInfo) resultObj.getData();
                        empLoginLog.setJwt(loginInfo.getToken());
                    }
                }
                empLoginLogService.insert(empLoginLog);
            }

            return result;
        } catch (Exception ex) {
            if (empLoginLog != null) {
                long endTime = System.currentTimeMillis();
                long costTime = endTime - startTime;
                empLoginLog.setCostTime((int) costTime);
                empLoginLog.setIsSuccess(0);
                empLoginLogService.insert(empLoginLog);
            }
            throw ex;
        } finally {
            // 清除开始时间
            startTimeThreadLocal.remove();
        }
    }

    // 用于存储开始时间
    private ThreadLocal<Long> startTimeThreadLocal = new ThreadLocal<>();
}
